home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / video / fly8111-.000 / fly8111- / fly8 / pitch.c < prev    next >
C/C++ Source or Header  |  1979-12-31  |  12KB  |  553 lines

  1. /* --------------------------------- pitch.c -------------------------------- */
  2.  
  3. /* This is part of the flight simulator 'fly8'.
  4.  * Author: Eyal Lebedinsky (eyal@ise.canberra.edu.au).
  5. */
  6.  
  7. /* paint the Head Up Display: pitch ladder
  8. */
  9.  
  10. #include "plane.h"
  11.  
  12.  
  13. /* Pendulum ticks:         5      15     30     45 */
  14. static int    F18Psin[] = {1428,  4240,  8192,  11585};
  15. static int    F18Pcos[] = {16322, 15827, 14189, 11585};
  16.  
  17. /* Pendulum ticks:         10     20     30     45 */
  18. static int    F16Psin[] = {2845,  5604,  8192,  11585};
  19. static int    F16Pcos[] = {16135, 15396, 14189, 11585};
  20.  
  21.  
  22. /* Get pull-up cue data.
  23. */
  24.  
  25. #define SAFETY    200
  26.  
  27. extern void FAR
  28. get_cue (OBJECT *p)
  29. {
  30.     OBJECT    *target;
  31.     ANGLE    a;
  32.     int    tt;
  33.     long    hh;
  34.     Ulong    dt;
  35.     LVECT    LL;
  36.  
  37.     tt = p->speed / VONE * 5;
  38.     hh = p->R[Z]/VONE;
  39.     if (tt <= 0 || hh < 0) {
  40.         a = DEG (90);
  41.         tt = FONE;
  42.     } else if (WE_MK82 == EX->weapon &&
  43.        T(target = EX->target) && target->id == EX->tid) {
  44.         Vsub (LL, target->R, p->R);
  45.         dt = lhypot3d (LL) / VONE;
  46.         if (dt <= SAFETY) {
  47.             a = DEG (90);
  48.             tt = 0;
  49.         } else if ((Uint)tt < dt-SAFETY)
  50.             goto std_cue;
  51.         else {
  52.             a  = ACOS (fdiv (iabs ((int)(LL[Z]/VONE)), (int)dt));
  53.             a += ASIN (fdiv (SAFETY, (int)dt));
  54.             a -= DEG (90);
  55.             if (a > p->a[X])
  56.                 tt = fdiv ((int)(dt-SAFETY), tt);
  57.             else
  58.                 tt = FONE;
  59.         }
  60.     } else {
  61. std_cue: ;
  62.         if (hh >= tt) {
  63.             a = DEG (-90);
  64.             tt = FONE;
  65.         } else {
  66.             a = -ASIN (fdiv ((int)hh, tt));
  67.             tt = -p->V[Z] / VONE * 5;
  68.             if (tt > hh)
  69.                 tt = fdiv ((int)hh, tt);
  70.             else
  71.                 tt = FONE;
  72.         }
  73.     }
  74.     a -= p->a[X];
  75.     EX->misc[16] = a;
  76.     EX->misc[17] = tt;
  77. }
  78. #undef SAFETY
  79.  
  80. extern void FAR
  81. show_pitch (HUD *h, VIEW *view, OBJECT *p, int sx, int sy, int maxx, int maxy,
  82.     int orgx, int orgy, int ttx, int tty, int tx, int ty, int ss,
  83.     int shifty, int type, int VVD[2])
  84. {
  85.     int    hud, hud1, hudtype, f16, color, ladder, funnel;
  86.     int    x, y, x0, y0, ex, tt;
  87.     int    i, j, xt, yt, dx, dy, dd, rev;
  88.     int    sroll, croll, pitch, xroll, yroll, xnum, ynum, xslant, yslant;
  89.     int    xgap, ygap, xtip, ytip, l, px, py, n, nn, ldegrees;
  90.     int    dx0, dy0, dx1, dy1;
  91.     ANGLE    langles, hudarea, a;
  92.     VECT    RR;
  93.  
  94.     hud = EX->hud;
  95.     hud1 = EX->hud1;
  96.     hudtype = hud1 & HUD_TYPES;
  97.     f16  = hudtype == HUD_F16;
  98.     ladder = EX->ladder;
  99.     funnel = T(ladder & LD_FUNNEL);
  100.  
  101.     sroll = p->siny;
  102.     croll = p->cosy;
  103.  
  104. /* Select ladder center (vv or waterline).
  105. */
  106.     if (!(EX->hud & HUD_VV) || (ladder & LD_FIXED) || EX->v[Y] < 2*VONE)
  107.         px = py = 0;
  108.     else {
  109.         get_vv (p, RR);
  110.         tt = fmul (RR[X], croll) + fmul (RR[Z], sroll);
  111.         tt = muldiv (tt, VVPERIOD-VVDELAY, VVPERIOD);
  112.         RR[X] = fmul (tt, croll);
  113.         RR[Z] = -fmul (tt, sroll);
  114.         screen_coords (view, RR);
  115.  
  116.         if ((Uint)RR[Y] <= iabs (RR[X])/2 ||
  117.             (Uint)RR[Y] <= iabs (RR[Z])/2)
  118.             goto noladder;
  119.         px = muldiv(RR[X], maxx, RR[Y]);
  120.         py = muldiv(RR[Z], maxy, RR[Y]);
  121.     }
  122.  
  123. /* Choose ladder pitch.
  124. */
  125.     if (HDT_HUD == type) {
  126.         hudarea = DEG2ANG (EX->hudarea);
  127.         y = muldiv (view->viewport->z, SIN (hudarea), COS (hudarea));
  128.         y += fmul (y, EX->hudshift);
  129.         if (y > view->viewport->maxy) {
  130.             y = fmul (view->viewport->z, FONE + EX->hudshift);
  131.             hudarea = ATAN (view->viewport->maxy, y);
  132.         }
  133.         langles = hudarea;
  134.     } else {
  135.         y = muldiv (view->viewport->maxy, sy, maxy);
  136.         langles = ATAN (y, view->viewport->z);
  137.         hudarea = 0;    /* avoid compiler warning */
  138.     }
  139.     ldegrees = ANG2DEG00 (langles);
  140.  
  141. #if 0
  142.     if (EX->hudmode & HM_DECLUTTER)
  143.         ldegrees *= 2;        /* sparse ladder only */
  144.     if (ldegrees < 300)
  145.         ldegrees = 1;        /* degrees per step */
  146.     else if (ldegrees < 500)     /* must be a factor of 90 */
  147.         ldegrees = 2;
  148.     else if (ldegrees < 1500)
  149.         ldegrees = 5;
  150.     else if (ldegrees < 2300)
  151.         ldegrees = 10;
  152.     else if (ldegrees < 4500)
  153.         ldegrees = 15;
  154.     else
  155.         ldegrees = 30;
  156. #else
  157.     if (EX->hudmode & HM_DECLUTTER)
  158.         ldegrees = fmul (ldegrees, FCON(1/1.25)); /* sparse ladder */
  159.     else
  160.         ldegrees = fmul (ldegrees, FCON(1/2.50)); /* full ladder */
  161.     if (ldegrees < 100)
  162.         ldegrees = 1;        /* degrees per step */
  163.     else if (ldegrees < 200)     /* must be a factor of 90 */
  164.         ldegrees = 2;
  165.     else if (ldegrees < 500)
  166.         ldegrees = 5;
  167.     else if (ldegrees < 1000)
  168.         ldegrees = 10;
  169.     else if (ldegrees < 1500)
  170.         ldegrees = 15;
  171.     else
  172.         ldegrees = 30;
  173. #endif
  174.     langles = DEG2ANG (ldegrees);    /* angle of step */
  175.  
  176.     if (HDT_HUD == type) {
  177.         x0 = muldiv (sx, langles, hudarea);
  178.         y0 = muldiv (sy, langles, hudarea);
  179.     } else {
  180.         x0 = muldiv (maxx, langles, ATAN (view->viewport->maxx,
  181.                 view->viewport->z));
  182.         y0 = muldiv (maxy, langles, ATAN (view->viewport->maxy,
  183.                 view->viewport->z));
  184.     }
  185.  
  186.     x0 = fmul (sroll, x0);
  187.     y0 = fmul (croll, y0);
  188.  
  189.     dd = num_size (9L, ss);
  190.  
  191.     if (ladder & LD_ERECT) {
  192.         xnum = fmul (croll, ss);
  193.         ynum = fmul (sroll, ss);
  194.     } else {
  195.         xnum = fmul (croll, 2*dd+2);
  196.         ynum = fmul (sroll, 2*dd+2);
  197.     }
  198.  
  199.     xt = fmul (sroll, 16*ss);
  200.     yt = fmul (croll, 16*ss);
  201.  
  202.     sroll = fmul (sroll, sy);    /* convert to hud pixels */
  203.     croll = fmul (croll, sx);
  204.  
  205. /* pull-up cue
  206. */
  207.     get_cue (p);
  208.  
  209.     if (!(EX->hud3 & HUD_CUE))
  210.         goto no_cue;
  211.  
  212.     a = (ANGLE)EX->misc[16];
  213.     if (DEG (-90) == a)
  214.         goto no_cue;
  215.  
  216.     xgap  = fmul (croll, PULLUPCUEGAP);
  217.     ygap  = fmul (sroll, PULLUPCUEGAP);
  218.     xroll = fmul (croll, PULLUPCUE);
  219.     yroll = fmul (sroll, PULLUPCUE);
  220.     xslant = fmul (croll, PULLUPCUETIP);
  221.     yslant = fmul (sroll, PULLUPCUETIP);
  222.     xtip = xt/(16*2);
  223.     ytip = yt/(16*2);
  224.  
  225.     x = orgx + px - muldiv (x0, a, langles);
  226.     y = orgy + py - muldiv (y0, a, langles);
  227.  
  228.     if (a > 0) {
  229.         if (keep_inside (&x, &y, xroll, -xroll, yroll, -yroll,
  230.                         orgx, orgy, sx, sy, shifty))
  231.             if (((Uint)st.present) % 250 < 125)
  232.                 goto no_cue;
  233.     }
  234.  
  235.     gr_color (ST_HFG);
  236.     add_segment (x-xgap, y+ygap, x-xroll, y+yroll, orgx,
  237.         orgy, sx, sy, shifty);
  238.     add_segment (x+xgap, y-ygap, x+xroll, y-yroll, orgx,
  239.         orgy, sx, sy, shifty);
  240.  
  241.     add_segment (x-xroll, y+yroll, x-xslant-xtip, y+yslant-ytip,
  242.         orgx,orgy, sx, sy, shifty);
  243.     add_segment (x+xroll, y-yroll, x+xslant-xtip, y-yslant-ytip,
  244.         orgx, orgy, sx, sy, shifty);
  245. no_cue:    ;
  246.  
  247.     if (!(hud & HUD_LADDER))
  248.         goto noladder;
  249.  
  250.     xgap  = fmul (croll, EX->ldgap);    /* gap pixels */
  251.     ygap  = fmul (sroll, EX->ldgap);
  252.  
  253.     xtip = fmul (sroll, EX->ldtip);        /* tip size */
  254.     ytip = fmul (croll, EX->ldtip);
  255.  
  256.     xslant = 0;
  257.     yslant = 0;
  258.  
  259.     a = p->a[X];
  260.     l = ANG2DEG (a);            /* degrees */
  261.     if (a >= 0) {
  262.         pitch = (int)(a % langles);
  263.         ex = (int)(a / langles);
  264.     } else {
  265.         a = -a;
  266.         pitch = langles - (int)(a % langles);
  267.         ex = -(int)(a / langles + 1);
  268.     }
  269.     pitch *= (90/ldegrees);
  270.     px += fmul (pitch, x0);
  271.     py += fmul (pitch, y0);
  272.  
  273.     color = ST_HFG;
  274.  
  275.     for (i = -3; i <= 3; ++i) {
  276.         x = px - i*x0;
  277.         y = py - i*y0;
  278.  
  279.         n = (ex + i) * ldegrees;
  280.         nn = n-l;
  281.  
  282.         if (n > 90) {
  283.             n = 180 - n;
  284.             rev = 1;
  285.         } else if (n < -90) {
  286.             n = -180 - n;
  287.             rev = 1;
  288.         } else
  289.             rev = 0;
  290.  
  291.         if (ladder & LD_COLOR)
  292.             color = n < 0 ? CC_LRED :
  293.                 (n > 0 ? CC_LBLUE : CC_LGRAY);
  294.         gr_color (color);
  295.  
  296.         tt = n ? EX->ldstep :
  297.             ((EX->equip & EQ_GEAR) ? EX->ldstepg : EX->ldstep0);
  298.         xroll = fmul (croll, tt);
  299.         yroll = fmul (sroll, tt);
  300.  
  301.         nn = abs(n);
  302.         if (90 == nn && (ladder & LD_ZENITH)) {
  303.             dx = 2*tx;
  304.             dy = 2*ty;
  305.             if (iabs(x) < (Uint)(sx-dx) &&
  306.                 y < sy-dy+shifty && y > -sy+dy+shifty) {
  307.                 x += orgx;
  308.                 y += orgy;
  309.                 gr_ellipse (x, y, dx, dy);
  310.                 if (n < 0) {
  311.                     tt = SIN (D90/2);
  312.                     dx = fmul (tt, dx);
  313.                     dy = fmul (tt, dy);
  314.                     gr_move (x-dx, y+dy);
  315.                     gr_draw (x+dx, y-dy);
  316.                     gr_move (x-dx, y-dy);
  317.                     gr_draw (x+dx, y+dy);
  318.                 }
  319.             }
  320.             continue;
  321.         }
  322.  
  323.         x += orgx;
  324.         y += orgy;
  325.  
  326.         if (rev) {
  327.             xt = -xt;
  328.             yt = -yt;
  329.             xtip = -xtip;
  330.             ytip = -ytip;
  331.             xnum = -xnum;
  332.             ynum = -ynum;
  333.             xroll = -xroll;
  334.             yroll = -yroll;
  335.             xgap = -xgap;
  336.             ygap = -ygap;
  337.         }
  338.  
  339.         if (ladder & LD_SLANT) {
  340.             if (90 == nn)
  341.                 xslant = yslant = 0;
  342.             else {
  343.                 xslant = muldiv (xt, nn, 16*90/2);
  344.                 yslant = muldiv (yt, nn, 16*90/2);
  345.                 if (funnel != (n < 0)) {
  346.                     xslant = -xslant;
  347.                     yslant = -yslant;
  348.                 }
  349.             }
  350.         }
  351.  
  352. /* Show the steps with tips.
  353. */
  354.         if (funnel) {
  355.             dx0 = xgap;        /* right tip root */
  356.             dy0 = ygap;
  357.             dx1 = xroll;        /* right step */
  358.             dy1 = yroll;
  359.         } else {
  360.             dx0 = xroll;        /* right step */
  361.             dy0 = yroll;
  362.             dx1 = xgap;        /* right tip root */
  363.             dy1 = ygap;
  364.         }
  365.         if ((nn || (ladder & LD_TIP0)) && nn != 90) {
  366.             if (n < 0 && (ladder & LD_NEGTIP)) {
  367.                 dx = -xtip;
  368.                 dy = -ytip;
  369.             } else {
  370.                 dx = xtip;
  371.                 dy = ytip;
  372.             }
  373.             add_segment (x+dx0, y-dy0, x+dx0+dx, y-dy0+dy,
  374.                 orgx, orgy, sx, sy, shifty);
  375.             add_segment (x-dx0, y+dy0, x-dx0+dx, y+dy0+dy,
  376.                 orgx, orgy, sx, sy, shifty);
  377.         }
  378.         if (n < 0 && EX->ldndash) {
  379.             add_dash (x+dx0, y-dy0, x+dx1+xslant, y-dy1+yslant,
  380.                 EX->ldndash, FCON(0.5), orgx, orgy+shifty,
  381.                 sx, sy);
  382.             add_dash (x-dx0, y+dy0, x-dx1+xslant, y+dy1+yslant,
  383.                 EX->ldndash, FCON(0.5), orgx, orgy+shifty,
  384.                 sx, sy);
  385.         } else {
  386.             add_segment (x+dx0, y-dy0, x+dx1+xslant, y-dy1+yslant,
  387.                 orgx, orgy, sx, sy, shifty);
  388.             add_segment (x-dx0, y+dy0, x-dx1+xslant, y+dy1+yslant,
  389.                 orgx, orgy, sx, sy, shifty);
  390.         }
  391.  
  392. /* Show the pitch numerals.
  393. */
  394.         if (n) {
  395.             dx0 = x-xroll;
  396.             dy0 = y+yroll;
  397.             dx1 = x+xroll;
  398.             dy1 = y-yroll;
  399.  
  400.             if (ladder & LD_ERECT) {
  401.                 dx = -((nn >= 10) ? dd : dd/2);
  402.                 dy = (ladder & LD_UNDER) ? ss : ss/2;
  403.                 dx0 += -xnum;
  404.                 dy0 +=  ynum;
  405.                 dx1 +=  xnum;
  406.                 dy1 += -ynum;
  407.             } else {
  408.                 stroke_angle (rev ? D180+p->a[Y] : p->a[Y]);
  409.                 if (ladder & LD_UNDER) {
  410.                     dx = xt/16;
  411.                     dy = yt/16;
  412.                 } else {
  413.                     dx = xt/(16*2);
  414.                     dy = yt/(16*2);
  415.                 }
  416.                 if (nn < 10) {
  417.                     dx0 += -xnum/2;
  418.                     dy0 +=  ynum/2;
  419.                 } else {
  420.                     dx0 += -xnum;
  421.                     dy0 +=  ynum;
  422.                 }
  423.                 dx1 +=  xnum/4;
  424.                 dy1 += -ynum/4;
  425.             }
  426.             if (!(ladder & LD_RIGHT))
  427.                 show_num (dx0+dx, dy0+dy, (long)nn, ss, color,
  428.                     orgx, orgy, sx, sy, shifty);
  429.             show_num (dx1+dx, dy1+dy, (long)nn, ss, color,
  430.                 orgx, orgy, sx, sy, shifty);
  431.         }
  432.  
  433.         if (rev) {
  434.             xt = -xt;
  435.             yt = -yt;
  436.             xtip = -xtip;
  437.             ytip = -ytip;
  438.             xnum = -xnum;
  439.             ynum = -ynum;
  440.             xgap = -xgap;
  441.             ygap = -ygap;
  442.         }
  443.     }
  444.     if (!(ladder & LD_ERECT))
  445.         stroke_angle (0);
  446. noladder:
  447.  
  448. /* Show ground pointer marks.
  449. */
  450.     if (EX->hud1 & HUD_PENDULUM && !(EX->hudmode & HM_DECLUTTER)) {
  451.         if (f16) {
  452.             dx0 = F16GPTICK;
  453.             dy0 = F16GPPOS;
  454.             x   = F16GPSIZE;
  455.         } else {
  456.             dx0 = F18GPTICK;
  457.             dy0 = F18GPPOS;
  458.             if (hudtype == HUD_ETHER) {
  459.                 x = FONE + dx0;
  460.             } else
  461.                 x = F18GPSIZE;
  462.         }
  463.         px = fmul (sx, x);
  464.         py = fmul (sy, x);
  465.         y = fmul (py, dx0);
  466.         dy0 = orgy + fmul (sy, dy0);
  467.         gr_color (ST_HFG);
  468.         gr_move (orgx, dy0+py);
  469.         gr_draw (orgx, dy0+py+y);
  470.         for (i = 0; i < 4; ++i) {
  471.             if (f16) {
  472.                 dx = F16Psin[i];
  473.                 dy = F16Pcos[i];
  474.             } else {
  475.                 dx = F18Psin[i];
  476.                 dy = F18Pcos[i];
  477.             }
  478.             dx = fmul (px, dx);        /* tick base */
  479.             dy = fmul (py, dy);
  480.             x = fmul (dx, dx0);        /* tick size */
  481.             y = fmul (dy, dx0);
  482.             if (0 == i || (f16 && i < 2)) {    /* small tick */
  483.                 x = (x+1)/2;
  484.                 y = (y+1)/2;
  485.             }
  486.             gr_move (orgx+dx,   dy0+dy); /* +ve */
  487.             gr_draw (orgx+dx+x, dy0+dy+y);
  488.             gr_move (orgx-dx,   dy0+dy); /* -ve */
  489.             gr_draw (orgx-dx-x, dy0+dy+y);
  490.         }
  491.  
  492. /* The ground pointer itself.
  493. */
  494.         a = p->a[Y];
  495.         if (a > DEG(50)) {
  496.             a = DEG(50);
  497.             j = 1;
  498.         } else if (a < -DEG(50)) {
  499.             a = -DEG(50);
  500.             j = 1;
  501.         } else
  502.             j = 0;
  503.         if (!j || (((int)st.present)&0x0080)) {
  504.             x  = SIN (a);
  505.             y  = COS (a);
  506.             dx = fmul (px, x);        /* arrow point */
  507.             dy = fmul (py, y);
  508.             xt = fmul (fmul (px, y), dx0/2); /* arrow base tip */
  509.             yt = fmul (fmul (py, x), dx0/2);
  510.             px = fmul (dx, dx0);        /* arrow mid base */
  511.             py = fmul (dy, dx0);
  512.             dx += orgx;
  513.             dy += dy0;
  514.  
  515.             gr_move (dx,       dy);
  516.             gr_draw (dx-px+xt, dy-py-yt);
  517.             gr_draw (dx-px-xt, dy-py+yt);
  518.             gr_draw (dx,       dy);
  519.         }
  520.     }
  521.  
  522. /* Zenith marker. Experimental.
  523. */
  524.     if (ladder & LD_SUN) {
  525.         int    D[2];
  526.  
  527.         RR[X] = p->T[X][Z];
  528.         RR[Y] = p->T[Y][Z];
  529.         RR[Z] = p->T[Z][Z];
  530.         screen_coords (view, RR);
  531.         dx = tx+(tx>>1);
  532.         dy = ty+(ty>>1);
  533.         i = h->flags & HF_ETHERFRAME;
  534.         if (i) {
  535.             px = h->maxx;
  536.             py = h->maxy;
  537.         } else {
  538.             px = h->sx;
  539.             py = h->sy;
  540.         }
  541.         px -= dx;
  542.         py -= dy;
  543.         j = clip_to_screen (D, RR, maxx, maxy, px, py, shifty);
  544.         if (j && i) {
  545.             clip_to_ether (h, D, px, py);
  546.             dx = h->ethertx;
  547.             dy = h->etherty;
  548.         }
  549.         gr_color (CC_WHITE);
  550.         gr_ellipse (orgx+D[X], orgy-D[Y], dx, dy);
  551.     }
  552. }
  553.